/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: fastProtocolHdr.h,v 1.1 2008-03-30 00:55:36 amaula Exp $
 *
 */
#ifndef _FASTPROTOCOLHDR_H_
#define _FASTPROTOCOLHDR_H_
#include "protocolID.h"

#define FASTPROTOCOL_NUMBER                            0x01

/**
 * When this flag is SET on outgoing packet, the HUB will
 * send ERROR REPORTS to sender. Possible error values
 * currently are: ERROR_LINK and ERROR_UNREACHABLE.
 * ( See their description )
 */
#define FASTPROTOCOL_FLAG_REPORT_ERROR                 PROTOCOL_FLAGBIT(0)


/**
 * When this flag is SET on outgoing packet, the HUB will
 * send status reports to sender. Possible status reports
 * are currently: STATUS_CONGESTION
 * ( See their description )
 */
#define FASTPROTOCOL_FLAG_REPORT_STATUS                PROTOCOL_FLAGBIT(1)


/**
 * If this flag is SET on incoming packet, this packet
 * is an STATUS REPORT. This packet carries no payload.
 * See the error type flag to determine the occured error.
 */
#define FASTPROTOCOL_FLAG_STATUS                       PROTOCOL_FLAGBIT(2)


/**
 * If this flag is SET on incoming packet, this packet
 * is an ERROR REPORT. This packet carries no payload.
 * See the status type flag to determine the occured event.
 */
#define FASTPROTOCOL_FLAG_ERROR                        PROTOCOL_FLAGBIT(3)


/**
 * When this flag is SET, FastProtocol frames are sent over
 * 'DelayedLink' WITHOUT paying attention to the delaying value.  This
 * is a Quick&Dirty hack over the Hub; So PLEASE don't use it when it
 * is not absolutely necessary!
 *
 */
#define FASTPROTOCOL_FLAG_LINK_NODELAYING              PROTOCOL_FLAGBIT(6)


/**
 * If this flag is SET on incoming packet, this packet will
 * NOT be buffered on outgoing streams ( in case of 
 * congestion, this packet is silently dropped ) Currently,
 * the notification message for congestion will NOT be sent
 * if the message is dropped.
 */
#define FASTPROTOCOL_FLAG_LINK_NOCACHING               PROTOCOL_FLAGBIT(7)


/**
 * If this flag is SET on incoming packet, it means that the
 * incoming packet is of type EXPLICIT_MULTICAST. This packet
 * has a special format:
 * - The 'target_client' field indicates the number of recipients
 *   for this packet.
 * - Recipients are listed AFTER header and BEFORE payload, so that
 *   each recipient address is fully qualified hubid (32 bits).
 *   Total size of extra recipients block is 'target_client * 4' bytes, 
 *   after which, the payload begins. NOTE: The address array MUST
 *   BE SORTED by HubID, otherwise the multicast will not work
 *   properly.
 * - The 'target_hub' field is reserved and should be left zero.
 * 
 * NOTE: The Multicast header is STRIPPED from the packet before
 * delivering to final recipient. The final recipient will only receive
 * an 'ordinary' dataframe with no knowledge of its multicast origin.
 *
 * Note, this is specified as 'EXPLICIT' multicast, because every 
 * packet must contain the target addresses. In the future, we may
 * implement a 'real', "flow-label" based multicast - IF required!
 */
#define FASTPROTOCOL_FLAG_MODE_EXPLICIT_MULTICAST      PROTOCOL_FLAGBIT(8)


/**
 * If this flag is SET on incoming packet, this packet
 * is an CONGESTION STATUS REPORT. 
 * This packet carries no payload. When this event happens,
 * it means that the packet has been delayed onroute to the
 * destination.
 */
#define FASTPROTOCOL_FLAG_STATUS_CONGESTION            PROTOCOL_FLAGBIT(11)


/**
 * If this flag is SET on incoming packet, this packet 
 * is an LINK ERROR REPORT. Link error report means that
 * the packet encountered a bad link during the route, and
 * the target is unreachable (not very big difference to
 * ERROR_UNREACHABLE)
 */
#define FASTPROTOCOL_FLAG_ERROR_LINK                   PROTOCOL_FLAGBIT(14)


/**
 * If this flag is SET on incoming packet, this packet is
 * an UNREACHABLE ERROR REPORT. Unreachable error means, that
 * the destination target is unknown. (Is not known to exists,
 * or no route to target exists (no hub route for example))
 *
 * More distinct error types may be specified in the future.
 */
#define FASTPROTOCOL_FLAG_ERROR_UNREACHABLE            PROTOCOL_FLAGBIT(15)




#define FASTPROTOCOL_DEFAULT_TTL                       8

#define FASTPROTOCOL_PAYLOAD2TOTAL(xyz) \
        ((xyz) + sizeof(TFastProtocolHeader))
#define FASTPROTOCOL_TOTAL2PAYLOAD(xyz) \
        ((xyz) - sizeof(TFastProtocolHeader))

/**
 * Link level protocol over tcpHub. Contains necessary data for interHUB
 * routing.
 */
typedef struct _fastProtocolHeader
{
  TProtocolIdentification protocol_id; ///< ID sizes 4 bytes

  unsigned char statusvalue;        ///< Status value; Depends on flags.
  unsigned char ttl;                ///< Time-To-Live (decremented on routing)
  unsigned short int flags;         ///< Protocol flags

  unsigned short int target_hub;    ///< Target HUB address
  unsigned short int target_client; ///< Target client address

  unsigned short int source_hub;    ///< Source HUB address
  unsigned short int source_client; ///< Source client address
} TFastProtocolHeader;

#define SIZEOF_TFASTPROTOCOLHEADER (16)
#endif
